﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AutoMapper;
using AutoPartsSearch.Domain.Abstract.Repositories;
using AutoPartsSearch.Domain.Entities;
using AutoPartsSearch.Domain.Entities.Enums;
using AutoPartsSearch.Web.Areas.Administration.Models.Dictionary;

namespace AutoPartsSearch.Web.Areas.Administration.Controllers
{
    public class DictionaryController : BaseAdminController
    {
        private IDictionaryRepository _repository;

        public DictionaryController(IDictionaryRepository repository)
        {
            this._repository = repository;
        }

        public ViewResult Add()
        {
            return View(new DictionaryModel());
        }

        [HttpPost]
        public ActionResult Add(DictionaryModel dictionaryModel)
        {
            if (!ModelState.IsValid)
            {
                return View(dictionaryModel);
            }

            var ruItems = dictionaryModel.Ru.Split('|');
            if (ruItems.Count() == 1)
            {
                var dict = Mapper.Map<Dictionary>(dictionaryModel);
                if (dictionaryModel.Id == null)
                    this._repository.Add(dict);
                else
                    this._repository.Update(dict);
            }else
            {
                AddManyDictionaries(dictionaryModel);
            }

            return RedirectToAction("List");
        }

        public ActionResult List(DictionaryType? dictionaryType)
        {
            IEnumerable<Dictionary> result;
            result = dictionaryType.HasValue
                ? this._repository.GetByType(dictionaryType.Value)
                : this._repository.Get();
            

            if (Request.IsAjaxRequest())
            {
                return Json(result, JsonRequestBehavior.AllowGet);
            }
            ViewBag.DictionaryTypes = GetDictionaryTypes(dictionaryType);
            return View(result);
        }

        [HttpPost]
        public ActionResult Delete(int id)
        {
            this._repository.Delete(id);
            return RedirectToAction("List");
        }

        public ActionResult Edit(int id)
        {
            var result = _repository.GetById(id);

            var dictModel = Mapper.Map<DictionaryModel>(result);
            return View("Add", dictModel);
        }

        [HttpPost]
        public ActionResult Edit(DictionaryModel dictionaryModel)
        {
            if (!ModelState.IsValid)
            {
                return View("Add", dictionaryModel);
            }
            return RedirectToAction("Add", dictionaryModel);
        }

        public JsonResult ByParentType(DictionaryType type)
        {
            var result = this._repository.GetByParentType(type).OrderBy(x => x.Name.Default);
            return Json(result, JsonRequestBehavior.AllowGet);
        }

        public JsonResult ByAdditionalParentType(DictionaryType type)
        {
            var result = this._repository.GetByAdditionalParentType(type).OrderBy(x => x.Name.Default);
            return Json(result, JsonRequestBehavior.AllowGet);
        }

        private void AddManyDictionaries(DictionaryModel dictionaryModel)
        {
            if (dictionaryModel.Id.HasValue)
            {
                throw new Exception("Cannot update multiple items.");
            }
            var ruItems = dictionaryModel.Ru.Split(new char[]{'|'}, StringSplitOptions.RemoveEmptyEntries);
            var roItems = dictionaryModel.Ro.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
            var enItems = dictionaryModel.En.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
            if (ruItems.Count() != roItems.Count() || ruItems.Count() != enItems.Count())
            {
                throw new Exception("Cannot add multiple items. Ru, Ro and En count should match.");
            }

            for (int i = 0; i < ruItems.Count(); i++)
            {
                var singleDictModel = new DictionaryModel
                                          {
                                              AdditionalParentId = dictionaryModel.AdditionalParentId,
                                              ParentId = dictionaryModel.ParentId,
                                              Type = dictionaryModel.Type,
                                              Ru = ruItems[i],
                                              Ro = roItems[i],
                                              En = enItems[i]
                                          };
                var dict = Mapper.Map<Dictionary>(singleDictModel);
                this._repository.Add(dict);
            }
        }

        private IEnumerable<SelectListItem> GetDictionaryTypes(DictionaryType? dictionaryType)
        {
            var result = new List<SelectListItem>()
                             {
                                 new SelectListItem()
                                     {
                                         Text = "All",
                                         Value = "All",
                                         Selected = false
                                     }
                             };
            result.AddRange(Enum.GetValues(typeof(DictionaryType))
                .Cast<DictionaryType>()
                .Select(m =>
                            {
                                string enumVal = m.ToString();
                                return new SelectListItem()
                                           {
                                               Selected = dictionaryType.HasValue && (dictionaryType.ToString() == enumVal),
                                               Text = enumVal,
                                               Value = enumVal
                                           };
                            })
               );
            return result;
        }
    }
}
